
import 'package:flutter_common/util/string_utils.dart';

extension ListExtension<E> on List<E> {
  void append(Iterable<E> iterable, bool appendList) {
    if(!appendList) {
      clear();
    }
    addAll(iterable);
  }
}

extension JsonUtilsExtension<K, V> on Map<K, V>? {
  /// 获取指定[key] 对应的int value,如果找不到，返回[defaultValue]
  int getInt(dynamic key, {int defaultValue = 0, List<dynamic>? alternate}) =>
      getNullableInt(key, defaultValue: defaultValue, alternate: alternate)!;

  /// 获取指定[key] 对应的int value,如果找不到，返回[defaultValue]
  int? getNullableInt(dynamic key,
      {int? defaultValue, List<dynamic>? alternate}) {
    final value = _getValue(key, alternate);
    if (value == null) {
      return defaultValue;
    }
    if(value == double.nan) {
      return defaultValue;
    }
    if (value is int) {
      return value;
    } else if(value is num) {
      try {
        return value.toInt();
      } catch (e) {
        return defaultValue;
      }
    } else if (value is String) {
      return value.toNullableInt(defaultValue: defaultValue, key: key);
    }
    return defaultValue;
  }

  /// 获取指定[key] 对应的double value,如果找不到，返回[defaultValue]
  double getDouble(dynamic key,
      {double defaultValue = 0, List<dynamic>? alternate}) =>
      getNullableDouble(key, defaultValue: defaultValue, alternate: alternate)!;

  /// 获取指定[key] 对应的double value,如果找不到，返回[defaultValue]
  double? getNullableDouble(dynamic key,
      {double? defaultValue, List<dynamic>? alternate}) {
    final value = _getValue(key, alternate);
    if (value == null) {
      return defaultValue;
    }
    if (value is double) {
      return value;
    } else if (value is int) {
      return value.toDouble();
    } else if (value is String) {
      return value.toNullableDouble(defaultValue: defaultValue);
    }
    return defaultValue;
  }

  /// 获取指定[key] 对应的String value,如果找不到，返回[defaultValue]
  String getString(dynamic key,
      {String defaultValue = "", List<dynamic>? alternate}) =>
      getNullableString(key, defaultValue: defaultValue, alternate: alternate)!;

  /// 获取指定[key] 对应的String value,如果找不到，返回[defaultValue]
  String? getNullableString(dynamic key,
      {String? defaultValue, List<dynamic>? alternate}) {
    final value = _getValue(key, alternate);
    if (value == null) {
      return defaultValue;
    }
    if (value is int || value is double || value is String) {
      return value.toString();
    }
    return defaultValue;
  }

  /// 获取指定[key] 对应的bool value,如果找不到，返回[defaultValue]
  bool getBool(dynamic key, {bool defaultValue = false}) {
    if (this == null) {
      return defaultValue;
    }
    final value = this![key];
    if (value == null) {
      return defaultValue;
    }
    if (value is bool) {
      return value;
    } else if (value is String) {
      if (value == 'true') {
        return true;
      } else if (value == 'false') {
        return false;
      } else {
        return value.toInt(defaultValue: 0) != 0;
      }
    } else if (value is int) {
      return value != 0;
    }
    return defaultValue;
  }

  /// 获取指定[key] 对应的字符串列表List,如果没有，则返回[List.empty(growable:true)]
  List<String> getStringList(dynamic key, {List<dynamic>? alternate}) =>
      getList<String>(key, (item) => item.toString(), alternate: alternate);

  /// 获取指定[key] 对应的整型列表List,如果没有，则返回[List.empty(growable:true)]
  List<int> getIntList(dynamic key,
      {List<dynamic>? alternate, int defaultValue = 0}) =>
      getList<int>(key, (value) {
        if (value is int) {
          return value;
        } else if (value is String) {
          return value.toNullableInt(defaultValue: defaultValue)!;
        }
        return defaultValue;
      }, alternate: alternate);

  /// 获取指定[key] 对应的List,通过[mapper]进行翻译，如果没有，则返回[List.empty(growable:true)]
  List<T> getList<T>(dynamic key, T Function(dynamic item) mapper,{List<dynamic>? alternate}) =>
      getNullableList(key, mapper, alternate: alternate) ?? List.empty(growable:true);

  /// 获取指定[key] 对应的List,通过[mapper]进行翻译，如果没有，则返回空
  List<T>? getNullableList<T>(dynamic key, T Function(dynamic item) mapper, {List<dynamic>? alternate}) {
    final value = _getValue(key, alternate);
    if (value is List) {
      final result = <T>[];
      for (var item in value) {
        result.add(mapper.call(item));
      }
      return result;
    }
    return null;
  }

  T getObject<T>(dynamic key, T Function() ifNotExist) {
    return getNullableObject<T>(key) ?? ifNotExist.call();
  }

  Map<E, F> getJsonObject<E, F>(E key) {
    if (this == null) {
      return {};
    }
    var value = this![key];
    if (value is Map<E, F>) {
      return value;
    }
    return {};
  }

  T? getNullableObject<T>(dynamic key) {
    if (this == null) {
      return null;
    }
    final value = this![key];
    if (value is T) {
      return value;
    }
    return null;
  }

  dynamic _getValue(dynamic key, List<dynamic>? alternate) {
    if (this == null) {
      return null;
    }
    final value = this![key];
    if (value != null) {
      return value;
    }
    if (alternate == null) {
      return null;
    }

    for (var item in alternate) {
      final value0 = this![item];
      if (value0 != null) {
        return value0;
      }
    }
    return null;
  }
}